package org.hsieh.tr.explore.util;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.Driver;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.hsieh.tr.explore.dbconn.JDBCClassLoader;
import org.hsieh.tr.explore.exception.ExceptionHandler;

public abstract class JarUtil {

    private static final String CLASS = ".class";

    @SuppressWarnings("unchecked")
    public static <T extends Driver> List<Class<T>> findDriverInJar(
	    String classpath) {
	if (classpath == null)
	    return null;
	try {
	    JarFile jarFile = new JarFile(classpath);
	    ClassLoader classLoader = new JDBCClassLoader(new URL[] { new File(
		    classpath).toURI().toURL() });

	    List<Class<T>> drivers = new ArrayList<Class<T>>();
	    for (Enumeration<JarEntry> iter = jarFile.entries(); iter
		    .hasMoreElements();) {
		JarEntry entry = iter.nextElement();
		int suffix = CLASS.length();
		if (!entry.isDirectory()) {
		    String entryName = entry.getName();
		    if (entryName.endsWith(CLASS)) {
			try {
			    /**
			     * Load class
			     */
			    String className = entryName.replaceAll("/", ".")
				    .substring(0, entryName.length() - suffix);

			    Class<?> klass = classLoader.loadClass(className);
			    Class<?>[] interfaces = klass.getInterfaces();
			    if (interfaces != null && interfaces.length > 0) {
				for (Class<?> pi : interfaces) {
				    if (pi == java.sql.Driver.class) {
					drivers.add((Class<T>) klass);
				    }
				}
			    }
			} catch (Throwable e) {
			    // e.printStackTrace();
			}
		    }// explore class file
		}
	    }
	    return drivers;
	} catch (IOException e) {
	    ExceptionHandler.handle(e);
	    return null;
	}
    }
}
